<template>
  <div>
    <el-form label-width="120px" :rules="rules" ref="formRef" :model="spuInfo">
      <el-form-item label="SPU名称" prop="spuName">
        <el-input placeholder="SPU名称" v-model="spuInfo.spuName"></el-input>
      </el-form-item>

      <el-form-item label="品牌" prop="tmId">
        <el-select placeholder="请选择" v-model="spuInfo.tmId">
          <el-option
            v-for="item in getAllTrademarkList"
            :label="item.tmName"
            :value="item.id!"
            :key="item.id"
          ></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="SPU描述" prop="description">
        <el-input
          type="textarea"
          placeholder="SPU描述"
          v-model="spuInfo.description"
        ></el-input>
      </el-form-item>

      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          v-model:file-list="spuInfo.spuImageList as any"
          :action="`${BASE_URL}/admin/product/fileUpload`"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleSuccess"
          multiple
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select :placeholder="ResidueSale()" v-model="idOrNameValue">
          <el-option
            v-for="item in residueSaleAttrList"
            :key="item.id"
            :label="item.name"
            :value="item.id + ':' + item.name"
          ></el-option>
        </el-select>
        <el-button
          type="primary"
          :icon="Plus"
          @click="addSaleAttrValue"
          :disabled="!idOrNameValue"
          >添加销售属性</el-button
        >
      </el-form-item>

      <el-form-item>
        <el-table
          border
          style="margin-top: 10px"
          :data="spuInfo.spuSaleAttrList"
        >
          <el-table-column
            label="序号"
            type="index"
            width="80"
            align="center"
          />
          <el-table-column label="属性名" prop="saleAttrName" width="120" />
          <el-table-column label="属性值名称列表">
            <template #default="{ row }">
              <el-tag
                v-for="(item, index) in row.spuSaleAttrValueList"
                style="margin-right: 5px"
                :key="item.id"
                closable
                @close="row.spuSaleAttrValueList.splice(index, 1)"
                >{{ item.saleAttrValueName }}
              </el-tag>
              <el-input
                v-if="row.isEdist"
                @blur="toShow(row)"
                ref="inputRef"
                style="width: 150px"
                v-model="saleAttrValue"
              ></el-input>
              <el-button
                v-else
                :icon="Plus"
                size="small"
                @click="toEdist(row)"
              ></el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120">
            <template v-slot="{ row, $index }">
              <el-button
                type="danger"
                :icon="Delete"
                size="small"
                @click="spuInfo.spuSaleAttrList.splice($index, 1)"
              ></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="submitForm" :loading="saveLoading"
          >保存</el-button
        >
        <el-button @click="emit('setShowState', SpuStates.SPU_LIST)">
          取消
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script lang="ts">
  import { defineComponent } from "vue";

  export default defineComponent({
    name: "SpuForm",
  });
</script>
<script lang="ts" setup>
  import { cloneDeep } from "lodash";
  import {
    addOrUpdateSpuInfoApi,
    getBaseSaleAttrListApi,
    getSpuImageListApi,
    getSpuSaleAttrListApi,
  } from "@/api/product/spu";
  import type { trademarkdListModel } from "@/api/product/model/trademarkdModel";
  import { SpuStates } from "../spu";
  import { ref, onMounted, computed, nextTick } from "vue";
  import { Plus, Delete } from "@element-plus/icons-vue";
  import type {
    BaseSaleAttrListModel,
    SpuSaleAttrModel,
    SpuValueModel,
  } from "@/api/product/model/spuModel";
  import { getAllTrademarkListApi } from "@/api/product/trademarkd";

  import {
    ElMessage,
    type FormInstance,
    type FormRules,
    type InputInstance,
    type UploadProps,
  } from "element-plus";

  const emit = defineEmits<{
    (e: "setShowState", value: SpuStates): void;
  }>();

  /* SUP图片 start */

  //利用代理解决上传图片路径跨域问题
  const BASE_URL = import.meta.env.VITE_BASE_URL;

  const dialogImageUrl = ref("");
  const dialogVisible = ref(false);

  // 点击删除回调
  // uploadFile: 要删除的图片对象
  // uploadFiles: 剩余的图片列表
  const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
    // console.log(uploadFile, uploadFiles);
    spuInfo.value.spuImageList = uploadFiles as any;
  };

  // 点击放大镜的回调
  // uploadFile: 点击的图片对象
  const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
    dialogImageUrl.value = uploadFile.url!;
    dialogVisible.value = true;
  };
  // 上传成功的回调
  // response: 上传请求的响应体数据  {data: 图片的url}
  // uploadFile: 上传成功的图片对象
  // uploadFiles: 已上传的图片列表
  const handleSuccess: UploadProps["onSuccess"] = (
    response,
    uploadFile,
    uploadFiles
  ) => {
    spuInfo.value.spuImageList = uploadFiles as any;
    // console.log(uploadFiles, "上传成功图片列表");
    formRef.value?.clearValidate();
  };
  /* SUP图片 end */

  /* 获取SpuList 传递过来的参数 */
  const prop = defineProps<{
    spuList: SpuValueModel;
  }>();
  //用于收集修改的值
  const spuInfo = ref<SpuValueModel>(prop.spuList);

  /* 初始化请求 start */

  // 基础销售属性列表类型初始化
  const getBaseSaleAttrList = ref<BaseSaleAttrListModel>([]);
  //有品牌列表初始化
  const getAllTrademarkList = ref<trademarkdListModel>([]);

  //获取所有品牌列表
  onMounted(async () => {
    getAllTrademarkList.value = await getAllTrademarkListApi();
  });
  //获取所有图片列表
  onMounted(async () => {
    if (!spuInfo.value.id) return;
    spuInfo.value.spuImageList = await getSpuImageListApi(spuInfo.value.id);
    spuInfo.value.spuImageList.map((item) => {
      item.name = item.imgName;
      item.url = item.imgUrl;
    });
  });
  //获取基础销售属性列表
  onMounted(async () => {
    getBaseSaleAttrList.value = await getBaseSaleAttrListApi();
  });
  //获取销售属性列表
  onMounted(async () => {
    if (!spuInfo.value.id) return;
    const getSpuSaleAttrList = await getSpuSaleAttrListApi(spuInfo.value.id!);
    spuInfo.value.spuSaleAttrList = getSpuSaleAttrList;
  });
  /* 初始化请求 end */

  //收集选择的销售属性
  const idOrNameValue = ref("");

  //点击添加销售属性列表
  const addSaleAttrValue = () => {
    const [id, name] = idOrNameValue.value.split(":");
    const addNewValue = {
      saleAttrName: name,
      baseSaleAttrId: +id,
      spuSaleAttrValueList: [],
    };
    spuInfo.value.spuSaleAttrList.push(addNewValue);
    idOrNameValue.value = "";
  };

  //销售属性列表的剩余列表
  const residueSaleAttrList = computed(() => {
    return getBaseSaleAttrList.value.filter((item) => {
      return !spuInfo.value.spuSaleAttrList.some(
        (i) => i.saleAttrName === item.name
      );
    });
  });

  const ResidueSale = () => {
    const length = residueSaleAttrList.value.length;
    return length === 0 ? `没有了` : `还有${length}个未选`;
  };

  /* 销售属性值的编辑与展示 start */
  const inputRef = ref<InputInstance>();
  const saleAttrValue = ref("");
  //点击按钮 切换编辑
  const toEdist = (row: SpuSaleAttrModel) => {
    row.isEdist = true;
    nextTick(() => {
      inputRef.value?.focus();
    });
  };
  //失去焦点 切换展示
  const toShow = (row: SpuSaleAttrModel) => {
    if (saleAttrValue.value) {
      const onRepetition = row.spuSaleAttrValueList.every(
        (item) => item.saleAttrValueName !== saleAttrValue.value
      );
      if (onRepetition) {
        const newValue = {
          baseSaleAttrId: row.baseSaleAttrId,
          saleAttrValueName: saleAttrValue.value,
        };
        row.spuSaleAttrValueList.push(newValue);
      }
    }
    row.isEdist = false;
    saleAttrValue.value = "";
  };
  /* 销售属性值的编辑与展示 end */

  /* 表单验证 start */
  const formRef = ref<FormInstance>();
  const rules: FormRules = {
    spuName: [{ required: true, message: "必须要填SPU名称" }],
    tmId: [{ required: true, message: "必须要选择品牌" }],
    description: [{ required: true, message: "必须要填SPU描述" }],
    spuImageList: [
      { required: true, message: "必须要上传SPU图片", type: "array" },
    ],
    spuSaleAttrList: [
      { required: true, message: "必须要添加销售属性", type: "array" },
    ],
  };
  const saveLoading = ref(false);
  //验证通过发送数据
  const submitForm = async () => {
    await formRef.value?.validate();

    const cloneSpuInfo = cloneDeep(spuInfo.value);

    cloneSpuInfo.spuImageList = cloneSpuInfo.spuImageList.map((item) => ({
      imgName: item.name!,
      imgUrl: item.response ? item.response.data : item.imgUrl,
    }));
    cloneSpuInfo.spuSaleAttrList = cloneSpuInfo.spuSaleAttrList.filter(
      (item) => {
        if (item.spuSaleAttrValueList.length > 0) {
          delete item.isEdist;
          return true;
        }
        return false;
      }
    );
    // 显示loading
    saveLoading.value = true;
    try {
      await addOrUpdateSpuInfoApi(cloneSpuInfo);
      ElMessage.success("保存成功");
      emit("setShowState", SpuStates.SPU_LIST);
      // saveLoading.value = false;
    } catch (error) {
      // saveLoading.value = false;
    } finally {
      saveLoading.value = false;
    }
  };
  /* 表单验证 end */
</script>

<style lang="scss" scoped></style>
